#include <iostream>
#include <chrono>
#include <thread>

#include "threadpool.h"

using namespace std;
using uLong = unsigned long long;

/*
* 有些场景, 是希望能够获取线程执行任务的返回值
* 举例:
* 求 1 + ... + 30000 的和
* thread1 1 + ... + 10000
* thread2 10001 + ... + 20000
* thread3 20001 + ... + 30000
* 
* main thread: 给每一个线程分配计算的区间, 并等待他们算完返回结果, 合并最终的结果即可
*/

class MyTask : public Task 
{
public:
	MyTask(int begin, int end)
		: begin_(begin)
		, end_(end)
	{}

	Any run()
	{
		std::cout << "tid:" << std::this_thread::get_id()
			<< "begin!" << std::endl;
		std::this_thread::sleep_for(std::chrono::seconds(5));
		uLong sum = 0;
		for (uLong i = begin_; i <= end_; i++)
			sum += i;
		std::cout << "tid:" << std::this_thread::get_id()
			<< "end!" << std::endl;

		return sum;
	}

private:
	int begin_;
	int end_;
};

int main() {
	{
		ThreadPool pool;
		pool.setMode(PoolMode::MODE_CACHED);
		pool.start(2);
		Result res1 = pool.submitTask(std::make_shared<MyTask>(1, 100000000));
		Result res2 = pool.submitTask(std::make_shared<MyTask>(100000001, 200000000));
		pool.submitTask(std::make_shared<MyTask>(100000001, 200000000));
		pool.submitTask(std::make_shared<MyTask>(100000001, 200000000));
		pool.submitTask(std::make_shared<MyTask>(100000001, 200000000));

		//uLong sum1 = res1.get().cast_<uLong>();
		//cout << sum1 << endl;

	} // 执行析构函数(包括Result对象)

	cout << "main over!" << endl;

	//getchar();


#if 0

	// 问题: ThreadPool对象析构以后, 怎么样把线程池相关的线程资源全部回收?
	{
		ThreadPool pool;
		pool.setMode(PoolMode::NODE_CACHED);
		pool.start(4);

		// 如何设计这里的Result机制?
		Result res1 = pool.submitTask(std::make_shared<MyTask>(1, 100000000));
		Result res2 = pool.submitTask(std::make_shared<MyTask>(100000001, 200000000));
		Result res3 = pool.submitTask(std::make_shared<MyTask>(200000001, 300000000));

		pool.submitTask(std::make_shared<MyTask>(300000001, 400000000));
		pool.submitTask(std::make_shared<MyTask>(400000001, 500000000));
		pool.submitTask(std::make_shared<MyTask>(500000001, 600000000));

		uLong sum1 = res1.get().cast_<uLong>(); // get返回了一个Any类型, 怎么转成具体的类型?
		uLong sum2 = res2.get().cast_<uLong>();
		uLong sum3 = res3.get().cast_<uLong>();

		cout << (sum1 + sum2 + sum3) << endl;
	} // ThreadPool资源回收

	getchar();

#endif

}